/*
 * @Author: your name
 * @Date: 2022-02-25 22:06:57
 * @LastEditTime: 2022-03-06 22:42:35
 * @LastEditors: Please set LastEditors
 * @Description: 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
 * @FilePath: \test\websocket_client.h
 */

#pragma once
#include <websocketpp/config/asio_client.hpp>
#include <websocketpp/config/asio_no_tls_client.hpp>
#include <websocketpp/client.hpp>
#include <iostream>
#include <string>
#include <functional>
#include <string.h> 

typedef websocketpp::client<websocketpp::config::asio_client> Client;
typedef websocketpp::client<websocketpp::config::asio_tls_client> TlsClient;

using websocketpp::lib::placeholders::_1;
using websocketpp::lib::placeholders::_2;
using websocketpp::lib::bind;

// pull out the type of messages sent by our config
typedef websocketpp::config::asio_client::message_type::ptr message_ptr;

class WebsocketClient {
public:
	enum CloseReason{
		PEER_CLOSED = 1,
		LOCAL_CLOSED = 2
	};

	typedef std::function<void (WebsocketClient *)> OnConnectedHandler;
	typedef std::function<void (WebsocketClient *,CloseReason)>  OnDisConnectedHandler;
	typedef std::function<void(WebsocketClient *, std::string )> OnReadHandler;
	
	enum Status
	{
		STOP =  0,
		CONNECTING = 1,
		CONNECTED = 2,
		FAIL = 3,
		CLOSED = 4,
	};
	
	Status State(){
		return m_status;
	}
	std::string Url();
	WebsocketClient(bool tls);
	WebsocketClient(std::string url,bool tls);
	int Connect(std::string);
	~WebsocketClient();
	void Close();
	int SendMsg(const char * str,uint32_t len,websocketpp::frame::opcode::value);
	friend void on_fail(WebsocketClient * c, websocketpp::connection_hdl hdl);
	friend void on_close(WebsocketClient * c, websocketpp::connection_hdl hdl);	
	friend void on_open(WebsocketClient * c, websocketpp::connection_hdl hdl);
	friend void on_message(WebsocketClient* c, websocketpp::connection_hdl hdl, message_ptr msg);
	int SetOnConnectedHandler(OnConnectedHandler on_connected);
	int SetOnDisConnectedHandler(OnDisConnectedHandler on_disconnected);
	int SetOnReadHandler(OnReadHandler onread);

private:
	uint32_t m_socketfd;
	Status m_status; // 当前服务器状态
	std::string m_url; // url
	Client m_client;  // 客户端
	TlsClient m_client_tls;
	std::thread *m_thread;  // 当前活动线程
	Client::connection_ptr m_conn;
	TlsClient::connection_ptr m_conn_tls;  // 客户端

	bool m_auto_reconn;
	bool m_tls;
	OnReadHandler m_onread;
	OnConnectedHandler m_on_connected;
	OnDisConnectedHandler m_on_disconnected;
};



